package priority_queue

import (
	"goscanner/utils/go_tools/link_list"
)

type Queue[T any] struct {
	valueQueue   map[int]*link_list.LinkList[T]
	defaultValue T
	maxPriority  int
}

func (q *Queue[T]) Init(defaultValue T) {
	q.valueQueue = make(map[int]*link_list.LinkList[T])
	q.defaultValue = defaultValue
}

func (q *Queue[T]) Push(priority int, value T) {
	if _, ok := q.valueQueue[priority]; !ok {
		q.valueQueue[priority] = &link_list.LinkList[T]{}
		q.valueQueue[priority].DefaultValue = q.defaultValue
	}
	q.valueQueue[priority].Push(value)
	if q.maxPriority < priority {
		q.maxPriority = priority
	}
}

func (q *Queue[T]) Pop() T {
	if values, ok := q.valueQueue[q.maxPriority]; ok && values.Head != nil {
		return values.Pop()
	}
	q.maxPriority = -99999
	for p, v := range q.valueQueue {
		if q.maxPriority < p && v.Head != nil {
			q.maxPriority = p
		}
	}
	if values, ok := q.valueQueue[q.maxPriority]; ok {
		return values.Pop()
	}
	return q.defaultValue
}
